using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NBusiness.Data.Providers.SqlServer.Query;

namespace NBusiness.Query.Testing
{
    [TestClass]
    public class QueryOperatorOverloadTests
    {
        [TestMethod]
        public void TestColumnEquals()
        {
            SqlColumn c1 = new SqlColumn("c1");
            string p1 = "@p1";
            SqlEqual actual = c1 == p1;

            Assert.IsNotNull(actual);
            Assert.IsFalse(actual.Not);
            Assert.AreSame(c1, actual.Left);
            Assert.IsTrue(actual.Right is SqlParameter);
            Assert.AreSame(p1, (actual.Right as SqlParameter).Name);

            string expected = "([c1]=@p1)";
            string actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);
        }

        [TestMethod]
        public void TestColumnNotEquals()
        {
            SqlColumn c1 = new SqlColumn("c1");
            string p1 = "@p1";
            SqlEqual actual = c1 != p1;

            Assert.IsNotNull(actual);
            Assert.IsTrue(actual.Not);
            Assert.AreSame(c1, actual.Left);
            Assert.IsTrue(actual.Right is SqlParameter);
            Assert.AreSame(p1, (actual.Right as SqlParameter).Name);

            string expected = "([c1]<>@p1)";
            string actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);
        }

        [TestMethod]
        public void TestColumnLessThan()
        {
            SqlColumn c1 = new SqlColumn("c1");
            string p1 = "@p1";
            SqlLessThan actual = (c1 < p1) as SqlLessThan;

            Assert.IsNotNull(actual);
            Assert.IsFalse(actual.OrEqual);
            Assert.AreSame(c1, actual.Left);
            Assert.IsTrue(actual.Right is SqlParameter);
            Assert.AreSame(p1, (actual.Right as SqlParameter).Name);

            string expected = "([c1]<@p1)";
            string actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);
        }

        [TestMethod]
        public void TestColumnLessThanOrEqual()
        {
            SqlColumn c1 = new SqlColumn("c1");
            string p1 = "@p1";
            SqlLessThan actual = (c1 <= p1) as SqlLessThan;

            Assert.IsNotNull(actual);
            Assert.IsTrue(actual.OrEqual);
            Assert.AreSame(c1, actual.Left);
            Assert.IsTrue(actual.Right is SqlParameter);
            Assert.AreSame(p1, (actual.Right as SqlParameter).Name);

            string expected = "([c1]<=@p1)";
            string actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);
        }

        [TestMethod]
        public void TestColumnGreaterThan()
        {
            SqlColumn c1 = new SqlColumn("c1");
            string p1 = "@p1";
            SqlGreaterThan actual = (c1 > p1) as SqlGreaterThan;

            Assert.IsNotNull(actual);
            Assert.IsFalse(actual.OrEqual);
            Assert.AreSame(c1, actual.Left);
            Assert.IsTrue(actual.Right is SqlParameter);
            Assert.AreSame(p1, (actual.Right as SqlParameter).Name);

            string expected = "([c1]>@p1)";
            string actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);
        }

        [TestMethod]
        public void TestColumnGreaterThanOrEqual()
        {
            SqlColumn c1 = new SqlColumn("c1");
            string p1 = "@p1";
            SqlGreaterThan actual = (c1 >= p1) as SqlGreaterThan;

            Assert.IsNotNull(actual);
            Assert.IsTrue(actual.OrEqual);
            Assert.AreSame(c1, actual.Left);
            Assert.IsTrue(actual.Right is SqlParameter);
            Assert.AreSame(p1, (actual.Right as SqlParameter).Name);

            string expected = "([c1]>=@p1)";
            string actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);
        }

        [TestMethod]
        public void TestColumnBooleanPrimitives()
        {
            SqlColumn c1 = new SqlColumn("c1");
            object value = "test";
            SqlEqual actual = c1 == value;
            Assert.IsTrue(actual.Right is SqlPrimitive);
            string expected = "([c1]='test')";
            string actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);

            value = new Guid("A5D88E15-FB93-4dfc-A38A-A577ED784014");
            actual = c1 == value;
            Assert.IsTrue(actual.Right is SqlPrimitive);
            expected = "([c1]='a5d88e15-fb93-4dfc-a38a-a577ed784014')";
            actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);

            value = new DateTime(2007, 11, 1, 20, 19, 34);
            actual = c1 == value;
            Assert.IsTrue(actual.Right is SqlPrimitive);
            expected = "([c1]='11/1/2007 8:19:34 PM')";
            actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);

            value = 100;
            actual = c1 == value;
            Assert.IsTrue(actual.Right is SqlPrimitive);
            expected = "([c1]=100)";
            actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);
        }

        [TestMethod]
        public void TestBooleanAnd()
        {
            SqlColumn c1 = new SqlColumn("c1");
            SqlColumn c2 = new SqlColumn("c2");
            string p1 = "@p1";
            string p2 = "@p2";
            SqlAnd actual = ((c1 == p1) & (c2 == p2)) as SqlAnd;

            Assert.IsNotNull(actual);
            Assert.IsTrue(actual.Left is SqlEqual);
            Assert.IsTrue(actual.Right is SqlEqual);
            Assert.AreSame(c1, (actual.Left as SqlEqual).Left);
            Assert.AreSame(c2, (actual.Right as SqlEqual).Left);

            Assert.IsTrue((actual.Left as SqlEqual).Right is SqlParameter);
            Assert.IsTrue((actual.Right as SqlEqual).Right is SqlParameter);
            Assert.AreEqual(p1, ((actual.Left as SqlEqual).Right as SqlParameter).Name);
            Assert.AreEqual(p2, ((actual.Right as SqlEqual).Right as SqlParameter).Name);

            string expected = "(([c1]=@p1) AND ([c2]=@p2))";
            string actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);
        }

        [TestMethod]
        public void TestBooleanOr()
        {
            SqlColumn c1 = new SqlColumn("c1");
            SqlColumn c2 = new SqlColumn("c2");
            string p1 = "@p1";
            string p2 = "@p2";
            SqlOr actual = ((c1 == p1) | (c2 == p2)) as SqlOr;

            Assert.IsNotNull(actual);
            Assert.IsTrue(actual.Left is SqlEqual);
            Assert.IsTrue(actual.Right is SqlEqual);
            Assert.AreSame(c1, (actual.Left as SqlEqual).Left);
            Assert.AreSame(c2, (actual.Right as SqlEqual).Left);

            Assert.IsTrue((actual.Left as SqlEqual).Right is SqlParameter);
            Assert.IsTrue((actual.Right as SqlEqual).Right is SqlParameter);
            Assert.AreEqual(p1, ((actual.Left as SqlEqual).Right as SqlParameter).Name);
            Assert.AreEqual(p2, ((actual.Right as SqlEqual).Right as SqlParameter).Name);

            string expected = "(([c1]=@p1) OR ([c2]=@p2))";
            string actualSql = actual.ToSql();
            Assert.AreEqual(expected, actualSql);
        }
    }
}
